/*
不安全操作

在整个代码库中，要尽可能减少不安全代码的量

在 Rust 中，不安全代码块用于避开编译器的保护策略；
具体地说，不安全代码块主要用于四件事情：
- 解引用裸指针
- 通过 FFI 调用函数
- 调用不安全的函数
- 内联汇编（inline assembly）
*/

// 原始指针（raw pointer，裸指针）* 和引用 &T 有类似的功能，但引用总是安全的，
// 因为借用检查器保证了它指向一个有效的数据。解引用一个裸指针只能通过不安全代码块执行。
fn f1() {
    let raw_p: *const u32 = &10;

    unsafe {
        assert!(*raw_p == 10);
    }
}

// 调用不安全函数
// 一些函数可以声明为不安全的（unsafe），
// 这意味着在使用它时保证正确性不再是编译器的责任，而是程序员的。
use std::slice;

fn f2() {
    let some_vector = vec![1,2,3,4];
    let pointer = some_vector.as_ptr();
    let length = some_vector.len();

    unsafe {
        // 向它传入指向第一个元素的指针和长度参数，它会创建一个切片
        // slice::from_raw_parts 假设传入的指针指向有效的内存，且被指向的内存
        // 具有正确的数据类型，我们必须满足这一假设，否则程序的行为是未定义的（undefined）
        let my_slice: &[u32] = slice::from_raw_parts(pointer, length);
        assert_eq!(some_vector.as_slice(), my_slice);
    }
}

fn main() {
    f1();
    f2();
}